


import concurrent.futures
import threading
from event_dispatcher import Event_Dispatcher
from event_type import EventType

class MultyThreadManager:
    
    def __init__(self):
        self.pools = {}
    
    def new_pools(self, room_id):
        if room_id not in self.pools:
            self.pools[room_id] = {}
            self.pool_main = concurrent.futures.ThreadPoolExecutor(max_workers = 1)
            self.pool_sub  = concurrent.futures.ThreadPoolExecutor(max_workers = 1)
            self.pools[room_id]["main"] = self.pool_main
            self.pools[room_id]["sub"] = self.pool_sub

    def shutdown_pools(self, room_id):
        def shutdown_pools_thread(room_id):
            if room_id in self.pools:
                pools = self.pools[room_id]
                pools["main"].shutdown()
                pools["sub"].shutdown()
                self.pools.pop(room_id)
        shutdown_thread = threading.Thread(target=shutdown_pools_thread, args=(room_id))
        shutdown_thread.start()
        # 使用join会导致主线程阻塞，执行完shutdown_pools_thread后才会继续执行
        # shutdown_thread.join()

    def init_listener(self):
        Event_Dispatcher.addListener(EventType.excute_cmd, self.excute_function)

    def excute_function(self, data, fun_tag):
        print(f"excute_function{fun_tag}")
        if "func" in data:
            self.pool_main.submit(self.sub_thread_excute_function, data)
        else:
            print(f"excute_function{fun_tag} error")
    
    def sub_thread_excute_function(self, data):
        print("sub_thread_excute_function")
        if "args" in data:
            fature = self.pool_sub.submit(data["func"], data["args"])
        else:
            fature = self.pool_sub.submit(data["func"])
        
        try:
            Event_Dispatcher.dispatchEvent(EventType.excute_cmd_end, fature.result())
            print(f"sub_thread_excute_function end {fature.result()}")
        except Exception as e:
            print(f"sub_thread_excute_function error{e}")
            Event_Dispatcher.dispatchEvent(EventType.excute_cmd_end, e)
    